package com.dbflow5.adapter;

import com.dbflow5.annotation.PrimaryKey;
import com.dbflow5.database.DatabaseStatement;
import com.dbflow5.database.DatabaseWrapper;
import ohos.data.rdb.ValuesBucket;

import java.util.Collection;

/**
 * Description: Used for our internal Adapter classes such as generated [ModelAdapter].
 */
public interface InternalAdapter<TModel> {

    /**
     * The table name of this adapter.
     *
     * @return The table name of this adapter.
     */
    String getName();

    /**
     * Saves the specified model to the DB.
     *
     * @param model           The model to save/insert/update
     * @param databaseWrapper The manually specified wrapper.
     * @return is success?
     */
    boolean save(TModel model, DatabaseWrapper databaseWrapper);

    /**
     * Saves a [Collection] of models to the DB.
     *
     * @param models          The [Collection] of models to save.
     * @param databaseWrapper The manually specified wrapper
     * @return the count of models saved or updated.
     */
    long saveAll(Collection<TModel> models, DatabaseWrapper databaseWrapper);

    /**
     * Inserts the specified model into the DB.
     *
     * @param model           The model to insert.
     * @param databaseWrapper The manually specified wrapper.
     * @return is success?
     */
    long insert(TModel model, DatabaseWrapper databaseWrapper);

    /**
     * Inserts a [Collection] of models into the DB.
     *
     * @param models          The [Collection] of models to save.
     * @param databaseWrapper The manually specified wrapper
     * @return the count inserted
     */
    long insertAll(Collection<TModel> models, DatabaseWrapper databaseWrapper);

    /**
     * Updates the specified model into the DB.
     *
     * @param model           The model to update.
     * @param databaseWrapper The manually specified wrapper.
     * @return is success?
     */
    boolean update(TModel model, DatabaseWrapper databaseWrapper);

    /**
     * Updates a [Collection] of models in the DB.
     *
     * @param models          The [Collection] of models to save.
     * @param databaseWrapper The manually specified wrapper
     * @return count of successful updates.
     */
    long updateAll(Collection<TModel> models, DatabaseWrapper databaseWrapper);

    /**
     * Deletes the model from the DB
     *
     * @param model           The model to delete
     * @param databaseWrapper The manually specified wrapper.
     * @return is success?
     */
    boolean delete(TModel model, DatabaseWrapper databaseWrapper);

    /**
     * Updates a [Collection] of models in the DB.
     *
     * @param models          The [Collection] of models to save.
     * @param databaseWrapper The manually specified wrapper
     * @return count of successful deletions.
     */
    long deleteAll(Collection<TModel> models, DatabaseWrapper databaseWrapper);

    /**
     * Binds to a [DatabaseStatement] for insert.
     *
     * @param sqLiteStatement The statement to bind to.
     * @param model           The model to read from.
     */
    void bindToInsertStatement(DatabaseStatement sqLiteStatement, TModel model);

    /**
     * Binds a [TModel] to the specified db statement
     *
     * @param contentValues The content values to fill.
     * @param model         The model values to put on the contentvalues
     */
    void bindToContentValues(ValuesBucket contentValues, TModel model);

    /**
     * Binds a [TModel] to the specified db statement, leaving out the [PrimaryKey.autoincrement]
     * column.
     *
     * @param contentValues The content values to fill.
     * @param model         The model values to put on the content values.
     */
    void bindToInsertValues(ValuesBucket contentValues, TModel model);

    /**
     * Binds values of the model to an update [DatabaseStatement]. It repeats each primary
     * key binding twice to ensure proper update statements.
     * @param updateStatement updateStatement
     * @param model model
     */
    void bindToUpdateStatement(DatabaseStatement updateStatement, TModel model);

    /**
     * Binds values of the model to a delete [DatabaseStatement].
     * @param deleteStatement deleteStatement
     * @param model model
     */
    void bindToDeleteStatement(DatabaseStatement deleteStatement, TModel model);

    /**
     * If a model has an autoincrementing primary key, then
     * this method will be overridden.
     *
     * @param model The model object to store the key
     * @param id    The key to store
     */
    void updateAutoIncrement(TModel model, Number id);

    /**
     * If the [InternalAdapter] can be cached.
     * @return true if the [InternalAdapter] can be cached.
     */
    boolean cachingEnabled();
}
